#define _CRT_SECURE_NO_WARNINGS 1
#include "string.h"

namespace bit
{
	const size_t string::npos = -1;
	 void string::reserve(int n)
	 {
		 if (n > _capacity)
		 {
			 char* tmp = new char[n + 1];
			 strcpy(tmp, _str);
			 delete[] _str;
			 _str = tmp;
			 _capacity = n;
		 }
	 }

	 void string::push_back(char ch)
	 {
		 if (_capacity == _size)
		 {
			 reserve(_capacity == 0 ? 4 : _capacity * 2);
		 }
		 _str[_size++] = ch;
		 _str[_size] = '\0';
	 }
	 void string::append(char ch)
	 {
		 push_back(ch);
	 }
	 void string::append(const char* str)
	 {
		 size_t len = strlen(str);
		 if (len + _size > _capacity)
		 {
			 reserve(_size + len > _capacity * 2 ? _size + len : _capacity * 2);
		 }
		 strcpy(_str + _size, str);
		 _size = _size + len;
	 }
	 void string::insert(size_t pos, char ch)
	 {
		 if (_capacity == _size)
		 {
			 reserve(_capacity == 0 ? 4 : _capacity * 2);
		 }
		 size_t end = _size + 1;
		 while (end > pos)
		 {
			 _str[end] = _str[end - 1];
			 end--;
		 }
		 _str[pos] = ch;
		 _size++;
	 }
	 void string::insert(size_t pos, const char* str)
	 {
		 size_t len = strlen(str);
		 if (len + _size > _capacity)
		 {
			 reserve(_size + len > _capacity * 2 ? _size + len : _capacity * 2);
		 }

		 size_t end = _size + len;
		 while (end > pos + len - 1)
		 {
			 _str[end] = _str[end - len];
			 end--;
		 }

		 for (size_t i = 0; i < len; i++)
		 {
			 _str[pos + i] = str[i];
		 }
		 _size = _size + len;
	 }
	 string& string::operator+=(const char* str)
	 {
		 append(str);
		 return *this;
	 }
	 string& string::operator+=(char ch)
	 {
		 append(ch);
		 return *this;
	 }

	 size_t string::find(char ch, size_t pos)
	 {
		 for (int i = 0; i < _size; i++)
		 {
			 if (_str[i] == ch)
			 {
				 return i;
			 }
		 }
		 return npos;
	 }
	 size_t string::find(const char* str, size_t pos)
	 {
		 const char* pst = strstr(_str, str);
		 if (pst == nullptr)
		 {
			 return npos;
		 }
		 return pst - _str;
	 }

	 void string::erase(size_t pos, size_t len)
	 {
		 if (len >= _size - pos)
		 {
			 _str[pos] = '\0';
			 _size = pos;
		 }
		 else {
			/* size_t end = pos + len;
			 while (end < _size + 1)
			 {
				 _str[end - len] = _str[end];
				 end--;
			 }
			 _size = _size - len;*/
			 for (size_t i = pos + len; i <= _size; i++)
			 {
				 _str[i - len] = _str[i];
			 }
			 _size = _size - len;
		 }
	 }
	 void string::clear()
	 {
		 _str[0] = '\0';
	 }
	 ostream& operator<<(ostream& out, const string& s)
	{
		 for (auto e : s)
		 {
			 out << e;
		 }
		 return out;
	}
		 istream& operator>>(istream& in, string& s)
	 {
			 char ch = in.get();
			 const int N = 256;
			 int i = 0;
			 char buff[N] = { 0 };
			 while (ch != ' ' && ch != '\n')
			 {
				 buff[i++] = ch;
				
				 if (i == N - 1)
				 {
					 buff[i] = '\0';
					 s += buff;
					 i = 1;
				 }
				 ch = in.get();
			 }
			 if (i > 0)
			 {
				 s += buff;
			 }
			 return in;
	 }
}